import { 
  AmbientLight,
  AnimationAction,
  AnimationMixer,
  CineonToneMapping,
  Clock,
  DoubleSide,
  LinearToneMapping,
  Material,
  Mesh,
  MeshStandardMaterial,
  NoToneMapping,
  PerspectiveCamera,
  PlaneGeometry,
  ReinhardToneMapping,
  Scene, 
  SpotLight, 
  WebGLRenderer
} from "three";
import stats from '../../utils/stats';
// 调用
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GUI } from 'dat.gui';
import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader";

let clock = new Clock();
let scene = new Scene();
let renderer = setRenderer();
let camera = setCamera();
let mixer: AnimationMixer;

setLight();
init();

const trackballControls = new OrbitControls(camera, renderer.domElement);
// 调整场景位置
trackballControls.target.set(0, 3, 0);

render();

function render() {
  stats.update();
  trackballControls.update();

  if (mixer) {
    mixer.update(clock.getDelta())
  }

  requestAnimationFrame(render);
  renderer.render(scene, camera);
}

function setRenderer() {
  const renderer = new WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 支持阴影生成 
  renderer.shadowMap.enabled = true;
  document.body.appendChild(renderer.domElement);

  return renderer
}

function setCamera(): PerspectiveCamera {
  let camera = new PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
  camera.position.set(0, 20, 40);
  scene.add( camera );

  return camera;
}

// 灯光设置
function setLight() {
  scene.add(new AmbientLight(0x444444));
  scene.add(new AmbientLight(0x343434));
  
  let spotLight = new SpotLight(0xffffff);
  spotLight.position.set(-10, 30, 40);
  spotLight.shadow.mapSize.width = 2048;
  spotLight.shadow.mapSize.height = 2048;
  spotLight.shadow.camera.fov = 15;
  spotLight.decay =2;
  spotLight.penumbra = 0.05;
  spotLight.castShadow = true;

  scene.add(spotLight);
  // scene.add(new SpotLightHelper(spotLight));
}

/** 功能区 */
function init() {
  let exrTextureLoader = new EXRLoader();
  let texture = (<any>exrTextureLoader).load('/textures/exr/Rec709.exr');

  let kont = new PlaneGeometry(20, 20);
  let mate = new MeshStandardMaterial({
    metalness: 0.2,
    roughness: 0.5,
    map: texture,
    side: DoubleSide,
  });
  let mesh = new Mesh(kont, mate);
  scene.add(mesh);

  addGUI(mesh);
}

function addGUI(mesh: Mesh): void {
  const gui = new GUI();
  gui.add(renderer, 'toneMappingExposure', 0, 2, 0.1);
  gui.add(renderer, 'toneMapping', {
    "NoToneMapping" : NoToneMapping,
    "LinearToneMapping" : LinearToneMapping,
    "ReinhardToneMapping" : ReinhardToneMapping,
    // "Uncharted2ToneMapping" : Uncharted2ToneMapping,
    // "Uncharted2ToneMapping" : Uncharted2ToneMapping,
    "CineonToneMapping" : CineonToneMapping
  }).onChange(val => {
    renderer.toneMapping = parseInt(val);
    (<Material>mesh.material).needsUpdate = true;
  })
}
